package com.winchain.chainbill.bill.biz.transfer.cmd;

import com.shell.bee.acct.transaction.po.AcctTxRec;
import com.shell.framework.command.CallbackContext;
import com.shell.framework.command.CommandContext;
import com.shell.framework.command.ICallback;
import com.shell.framework.command.ICommand;
import com.winchain.chainbill.basic.context.TimeoutOperation;
import com.winchain.chainbill.bill.base.po.CbOpt;
import com.winchain.chainbill.bill.base.po.CbRec;
import com.winchain.chainbill.bill.base.po.CbXfe;
import com.winchain.chainbill.bill.base.service.CbXfeService;
import com.winchain.chainbill.bill.biz.Bill;
import com.winchain.chainbill.bill.biz.BillEvent;
import com.winchain.chainbill.bill.biz.send.rx.BillMoveSubscriber;
import com.winchain.chainbill.bill.biz.send.rx.BillOptSubscriber;
import com.winchain.chainbill.bill.biz.transfer.rx.BillXfeSubscriber;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import rx.Observable;

@Component
public class BillXfeCmd implements ICommand<Bill<CbXfe>>, ICallback<Bill<CbXfe>, AcctTxRec> {
	@Autowired
	private CbXfeService cbXfeService;
	@Autowired
	private BillOptSubscriber billOptSubscriber;
	@Autowired
	private BillMoveSubscriber billMoveSubscriber;
	@Autowired
	private BillXfeSubscriber billXfeSubscriber;

	public boolean execute(CommandContext<Bill<CbXfe>> context) throws Exception {
		CbRec record = ((Bill) context.getSource()).getRec();
		CbXfe cbXfe = (CbXfe) ((Bill) context.getSource()).getSource();

		Object timeOut = context.getValue("Timeout");
		CbOpt cbOpt;
		if ((timeOut != null) && (((Boolean) timeOut).booleanValue())) {
			Object children = context.getValue("children");
			if (children != null) {
				List<Bill<CbXfe>> bills = (List) children;

				TimeoutOperation timeoutOperation = (TimeoutOperation) context.getValue("TimeoutOperation");
				cbOpt = new CbOpt();
				cbOpt.setOptCode(timeoutOperation.getOptCode());
				cbOpt.setRemark(timeoutOperation.getRemark());
				for (Bill<CbXfe> bill : bills) {
					((CbXfe) bill.getSource()).setXfeState("0");

					BillEvent<CbXfe> event = new BillEvent(bill);

					event.setOperation(cbOpt);

					Observable<BillEvent<CbXfe>> observers = Observable.just(event);

					observers.subscribe(this.billOptSubscriber);
					observers.subscribe(this.billMoveSubscriber);
					observers.subscribe(this.billXfeSubscriber);
				}
			}
		}
		if ((cbXfe != null) && (cbXfe.getXfeId() != null)) {
			cbXfe.setOptSeq(record.getOptSeq());
			this.cbXfeService.saveOrUpdate(cbXfe);
		}
		return false;
	}

	public boolean callback(CallbackContext<Bill<CbXfe>, AcctTxRec> context) throws Exception {
		execute(context);
		return false;
	}
}
